home *** CD-ROM | disk | FTP | other *** search
- Subject: v07i002: Tools to read damaged tar tapes (tar_aids)
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: pyramid!utzoo!henry
- Mod.sources: Volume 7, Issue 2
- Archive-name: tar_aids
-
-
- [ I wrote the Makefile and repacked the archive. These tools are
- very useful! --r$ ]
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
-
- # Exit status; set to 1 on "wc" errors or if would overwrite.
- STATUS=0
- # Contents: README Makefile targ.1 targ.c tarl.c
-
- echo x - README
- if test -f README ; then
- echo README exists, putting output in $$README
- OUT=$$README
- STATUS=1
- else
- OUT=README
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F README//'
- XXHere are two small public-domain programs for scavenging files from
- XXdamaged tar tapes. They don't sing or dance, but they are highly
- XXportable, and they are simple enough that they are readily understood
- XXand changed to meet special requirements. They aren't the most
- XXbeautiful code on Earth, since they are basically cleaned-up versions
- XXof quick-and-dirty improvisations. They do, however, work.
- @//E*O*F README//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - Makefile
- if test -f Makefile ; then
- echo Makefile exists, putting output in $$Makefile
- OUT=$$Makefile
- STATUS=1
- else
- OUT=Makefile
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F Makefile//'
- XXall: targ tarl
-
- XXtarg: targ.c
- XX cc $(CFLAGS) -o $@ $<
-
- XXtarl: tarl.c
- XX cc $(CFLAGS) -o $@ $<
-
- XX# The 'echo' causes the "right thing" to happen on 4.[23]BSD systems.
- XXDEST = /usr/local/bin
- XXMAN = /usr/man/man1
- XXinstall: all
- XX cp targ tarl $DEST
- XX cp targ.1 $MAN/targ.1
- XX echo ".so man1/tarl.1" >$MAN/targ.1
- @//E*O*F Makefile//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - targ.1
- if test -f targ.1 ; then
- echo targ.1 exists, putting output in $$targ.1
- OUT=$$targ.1
- STATUS=1
- else
- OUT=targ.1
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F targ.1//'
- XX.TH TARG 1 local
- XX.DA 23 July 1986
- XX.SH NAME
- XXtarg, tarl \- recover files from damaged tar-format archives
- XX.SH SYNOPSIS
- XX\fBtarg\fR file ...
- XX.PP
- XX\fBtarl\fR
- XX.SH DESCRIPTION
- XX\fITarg\fR and \fItarl\fR are used to list and recover files from a
- XXdamaged \fItar\fR(1) archive.
- XXThey use a simplistic pattern-matching
- XXapproach to identify \fItar\fR header blocks.
- XXBoth will cheerfully ignore all sorts of bad things about the archive
- XX(such as wrong checksums, read errors, and scraped-off magnetic surface...),
- XXup to a maximum of twenty hard errors in a row.
- XXThey report on such things as apparent end-of-file.
- XXBoth programs read the \fItar\fR archive from standard input.
- XX.PP
- XX\fITarl\fR lists the file names it sees in the archive.
- XXIt is particularly useful for
- XXpreparing a file of names for use with \fItarg\fR.
- XX.PP
- XX\fITarg\fR takes file or directory names as arguments
- XXand attempts to extract them from the archive.
- XX\fITarg\fR is not willing to create directories, however,
- XXso these must be made manually beforehand if they do not already exist.
- XXFiles are owned by the user, and have his default permissions.
- XX.SH EXAMPLE
- XX``tarl < /dev/rmt8 > filelist'' lists all files on the tape
- XXmounted on /dev/rmt8 and places the results in ``filelist''.
- XX.PP
- XX``targ joe/precious < /dev/rmt0'' restores the file
- XX``joe/precious'' from the tape mounted on /dev/rmt0.
- XXThe directory ``joe'' must already exist.
- XX.SH SEE ALSO
- XXtar(1)
- XX.SH HISTORY
- XXWritten by Henry Spencer, Univ. of Toronto Zoology.
- XXThis software is public domain.
- XXManual page by Chris Robertson.
- XX.SH BUGS
- XX\fITarg\fR should be smarter about directories and permissions.
- XX.PP
- XXThey really should use the \fItar\fR header-block checksum,
- XXinstead of the slightly-arcane pattern matcher, to identify header blocks.
- @//E*O*F targ.1//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - targ.c
- if test -f targ.c ; then
- echo targ.c exists, putting output in $$targ.c
- OUT=$$targ.c
- STATUS=1
- else
- OUT=targ.c
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F targ.c//'
- XX#include <stdio.h>
-
- XX#define NAMSIZ 100
- XXstruct matches {
- XX int offset;
- XX char value;
- XX} matches[] = {
- XX NAMSIZ+6, ' ',
- XX NAMSIZ+7, '\0',
- XX NAMSIZ+8+6, ' ',
- XX NAMSIZ+8+7, '\0',
- XX NAMSIZ+16+6, ' ',
- XX NAMSIZ+16+7, '\0',
- XX NAMSIZ+24+11, ' ',
- XX NAMSIZ+36+11, ' ',
- XX NAMSIZ+48+6, '\0',
- XX 0, 0,
- XX};
-
- XXint
- XXistar(block)
- XXchar *block;
- XX{
- XX int loop;
-
- XX for (loop = 0; matches[loop].offset != 0; loop++)
- XX if (block[matches[loop].offset] != matches[loop].value)
- XX return(0);
- XX return(1);
- XX}
-
- XXchar buf[10240];
- XXint bad;
- XXint nleft = 0;
- XXint whichnow;
-
- XXint opened = 0;
- XXint f;
- XXlong nwrite;
-
- XXmain(argc, argv)
- XXint argc;
- XXchar **argv;
- XX{
- XX int loop;
- XX char *block;
- XX extern char *readblock();
-
- XX bad = 0;
-
- XX for(;;) {
- XX block = readblock(0);
-
- XX if (block != NULL)
- XX doblock(block, argc, argv);
- XX }
- XX}
-
- XXdoblock(block, argc, argv)
- XXchar *block;
- XXint argc;
- XXchar **argv;
- XX{
- XX int count;
-
- XX if (istar(block)) {
- XX if (opened) {
- XX printf("--- premature end\n");
- XX close(f);
- XX opened = 0;
- XX }
- XX if (match(block, argc, argv)) {
- XX f = creat(block, 0666);
- XX if (f < 0)
- XX printf("--- unable to create %s\n", block);
- XX else {
- XX opened = 1;
- XX sscanf(block+NAMSIZ+24, "%lo", &nwrite);
- XX printf("--- reading %s %ld\n", block, nwrite);
- XX if (nwrite <= 0) {
- XX close(f);
- XX opened = 0;
- XX printf("--- done\n");
- XX }
- XX }
- XX }
- XX } else {
- XX if (opened) {
- XX count = (nwrite > 512) ? 512 : (int)nwrite;
- XX write(f, block, count);
- XX nwrite -= count;
- XX if (nwrite <= 0) {
- XX opened = 0;
- XX close(f);
- XX printf("--- done\n");
- XX }
- XX }
- XX }
- XX}
-
- XXint
- XXmatch(s, argc, argv)
- XXchar *s;
- XXint argc;
- XXchar **argv;
- XX{
- XX int i;
- XX int c;
-
- XX for (i = 1; i < argc; i++) {
- XX if (strncmp(s, argv[i], strlen(argv[i])) == 0) {
- XX c = s[strlen(argv[i])];
- XX if (c == '\0' || c == '/')
- XX return(1);
- XX }
- XX }
- XX return(0);
- XX}
-
- XXchar *
- XXreadblock(desc)
- XXint desc;
- XX{
- XX int count;
-
- XX if (nleft > 0) {
- XX whichnow++;
- XX nleft--;
- XX return(buf+whichnow*512);
- XX }
-
- XX count = read(desc, buf, (int)sizeof(buf));
- XX if (count <= 0 || count%512 != 0) {
- XX if (count == 0)
- XX printf("---apparent EOF\n");
- XX else
- XX printf("---error\n");
- XX if (bad > 20)
- XX exit(1);
- XX bad++;
- XX return(NULL);
- XX }
- XX bad = 0;
- XX whichnow = 0;
- XX nleft = count/512 - 1;
- XX return(buf);
- XX}
- @//E*O*F targ.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - tarl.c
- if test -f tarl.c ; then
- echo tarl.c exists, putting output in $$tarl.c
- OUT=$$tarl.c
- STATUS=1
- else
- OUT=tarl.c
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F tarl.c//'
- XX#include <stdio.h>
-
- XX#define NAMSIZ 100
- XXstruct matches {
- XX int offset;
- XX char value;
- XX} matches[] = {
- XX NAMSIZ+6, ' ',
- XX NAMSIZ+7, '\0',
- XX NAMSIZ+8+6, ' ',
- XX NAMSIZ+8+7, '\0',
- XX NAMSIZ+16+6, ' ',
- XX NAMSIZ+16+7, '\0',
- XX NAMSIZ+24+11, ' ',
- XX NAMSIZ+36+11, ' ',
- XX NAMSIZ+48+6, '\0',
- XX 0, 0,
- XX};
-
- XXint
- XXistar(block)
- XXchar *block;
- XX{
- XX int loop;
-
- XX for (loop = 0; matches[loop].offset != 0; loop++)
- XX if (block[matches[loop].offset] != matches[loop].value)
- XX return(0);
- XX return(1);
- XX}
-
- XXchar buf[10240];
- XXint bad;
- XXint nleft = 0;
- XXint whichnow;
-
- XXmain()
- XX{
- XX int loop;
- XX int dir;
- XX char *block;
- XX extern char *readblock();
-
- XX bad = 0;
-
- XX for(;;) {
- XX block = readblock(0);
-
- XX if (block != NULL && istar(block))
- XX printf("%s\n", block);
- XX }
- XX}
-
- XXchar *
- XXreadblock(desc)
- XXint desc;
- XX{
- XX int count;
-
- XX if (nleft > 0) {
- XX whichnow++;
- XX nleft--;
- XX return(buf+whichnow*512);
- XX }
-
- XX count = read(desc, buf, (int)sizeof(buf));
- XX if (count <= 0 || count%512 != 0) {
- XX if (count == 0)
- XX printf("---apparent EOF\n");
- XX else
- XX printf("---error\n");
- XX if (bad > 20)
- XX exit(1);
- XX bad++;
- XX return(NULL);
- XX }
- XX bad = 0;
- XX whichnow = 0;
- XX nleft = count/512 - 1;
- XX return(buf);
- XX}
- @//E*O*F tarl.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo Inspecting for damage in transit...
- temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 6 60 398 README
- 15 48 295 Makefile
- 46 274 1744 targ.1
- 147 329 2148 targ.c
- 81 163 1112 tarl.c
- 295 874 5697 total
- !!!
- wc $FILES | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if test -s $dtemp ; then
- echo "Ouch [diff of wc output]:"
- cat $dtemp
- STATUS=1
- elif test $STATUS = 0 ; then
- echo "No problems found."
- else
- echo "WARNING -- PROBLEMS WERE FOUND..."
- fi
- exit $STATUS
-